package com.benzhitech.core;

import io.netty.handler.codec.http.HttpMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * HTTP 路由管理器。
 * 存储 URI 和 HTTP 方法到 RouteHandler 的映射。
 */
public class Router {

    private static final Logger log = LoggerFactory.getLogger(Router.class);

    // 精确匹配的路由: Map<HttpMethod, Map<String, RouteHandler>>
    private final Map<HttpMethod, Map<String, RouteHandler>> exactRoutes = new HashMap<>();
    
    // 正则表达式匹配的路由: Map<HttpMethod, List<RegexRouteMapping>>
    private final Map<HttpMethod, List<RegexRouteMapping>> regexRoutes = new HashMap<>();

    /**
     * 添加精确匹配路由。
     *
     * @param method HTTP 方法
     * @param path URI 路径
     * @param handler 处理该路由的 RouteHandler
     */
    public void addRoute(HttpMethod method, String path, RouteHandler handler) {
        if (path.contains("*") || path.contains("{")) {
            // 包含通配符或路径参数，添加到正则路由
            addRegexRoute(method, path, handler);
        } else {
            // 精确路径匹配
            exactRoutes.computeIfAbsent(method, k -> new HashMap<>()).put(path, handler);
            log.info("添加精确匹配路由: {} {}", method, path);
        }
    }
    
    /**
     * 添加正则表达式匹配的路由
     * 支持 * 通配符和 {param} 形式的路径参数
     */
    private void addRegexRoute(HttpMethod method, String path, RouteHandler handler) {
        // 转换路径模式为正则表达式
        String regex = pathToRegex(path);
        Pattern pattern = Pattern.compile(regex);
        
        // 创建正则路由映射
        RegexRouteMapping mapping = new RegexRouteMapping(pattern, path, handler);
        
        // 添加到对应 HTTP 方法的列表中
        regexRoutes.computeIfAbsent(method, k -> new ArrayList<>()).add(mapping);
        log.info("添加正则匹配路由: {} {} (regex: {})", method, path, regex);
    }

    /**
     * 将路径模式转换为正则表达式
     * 例如: /static/*.html -> /static/.*\.html
     * 或者: /users/{id} -> /users/([^/]+)
     */
    private String pathToRegex(String path) {
        // 转义特殊字符 . 
        String escaped = path.replace(".", "\\.");
        
        // 将 * 转换为 .*
        String regex = escaped.replace("*", ".*");
        
        // 将 {param} 转换为 ([^/]+)
        Pattern paramPattern = Pattern.compile("\\{([^/]+)\\}");
        Matcher matcher = paramPattern.matcher(regex);
        StringBuffer sb = new StringBuffer();
        
        while (matcher.find()) {
            // 将 {param} 替换为捕获组
            matcher.appendReplacement(sb, "([^/]+)");
        }
        matcher.appendTail(sb);
        
        return "^" + sb.toString() + "$";
    }

    /**
     * 根据 HTTP 方法和 URI 路径查找对应的 RouteHandler。
     *
     * @param method HTTP 方法
     * @param path URI 路径
     * @return 匹配的 RouteHandler，如果未找到则返回 null
     */
    public RouteHandler findHandler(HttpMethod method, String path) {
        // 1. 先尝试精确匹配
        Map<String, RouteHandler> methodRoutes = exactRoutes.get(method);
        if (methodRoutes != null) {
            RouteHandler handler = methodRoutes.get(path);
            if (handler != null) {
                return handler;
            }
        }
        
        // 2. 如果没有精确匹配，尝试正则匹配
        List<RegexRouteMapping> regexMappings = regexRoutes.get(method);
        if (regexMappings != null) {
            for (RegexRouteMapping mapping : regexMappings) {
                if (mapping.matches(path)) {
                    log.debug("找到正则匹配路由: {} -> {}", path, mapping.getOriginalPath());
                    return mapping.getHandler();
                }
            }
        }
        
        // 没有找到匹配的路由
        return null;
    }

    /**
     * 辅助方法，添加 GET 路由。
     */
    public void get(String path, RouteHandler handler) {
        addRoute(HttpMethod.GET, path, handler);
    }

    /**
     * 辅助方法，添加 POST 路由。
     */
    public void post(String path, RouteHandler handler) {
        addRoute(HttpMethod.POST, path, handler);
    }
    
    /**
     * 辅助方法，添加 PUT 路由。
     */
    public void put(String path, RouteHandler handler) {
        addRoute(HttpMethod.PUT, path, handler);
    }
    
    /**
     * 辅助方法，添加 DELETE 路由。
     */
    public void delete(String path, RouteHandler handler) {
        addRoute(HttpMethod.DELETE, path, handler);
    }
    
    /**
     * 正则路由映射，存储正则表达式 Pattern 和对应的 RouteHandler
     */
    private static class RegexRouteMapping {
        private final Pattern pattern;
        private final String originalPath;
        private final RouteHandler handler;
        
        public RegexRouteMapping(Pattern pattern, String originalPath, RouteHandler handler) {
            this.pattern = pattern;
            this.originalPath = originalPath;
            this.handler = handler;
        }
        
        public boolean matches(String path) {
            return pattern.matcher(path).matches();
        }
        
        public String getOriginalPath() {
            return originalPath;
        }
        
        public RouteHandler getHandler() {
            return handler;
        }
    }
} 